package github.sf.fw.tools.security;

import javax.crypto.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;

/**
 * 对称加密
 *
 * @author zhoup
 * @since 2023/6/21
 */
public class AESEncrypt {
    public String encode(String content, String secretKey) {
        byte[] encrypt = encrypt(content.getBytes(), secretKey.getBytes());
        return Base64.getEncoder().encodeToString(encrypt);
    }

    public String decode(String content, String secretKey) {
        byte[] cipherBytes = Base64.getDecoder().decode(content);
        byte[] decrypt = decrypt(cipherBytes, secretKey.getBytes());
        return new String(decrypt);
    }

    public SecretKey generateSecretKey(byte[] key) {
        try {
            // 根据指定的 RNG 算法, 创建安全随机数生成器
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
            // 设置 密钥key的字节数组 作为安全随机数生成器的种子
            random.setSeed(key);
            // 创建 AES算法生成器
            KeyGenerator gen = KeyGenerator.getInstance("AES");
            // 初始化算法生成器
            gen.init(128, random);
            // 生成 AES密钥对象, 也可以直接创建密钥对象: return new SecretKeySpec(key, ALGORITHM);
            return gen.generateKey();
        } catch (NoSuchAlgorithmException e) {
            throw new SecurityException(e);
        }
    }

    /**
     * 数据加密: 明文 -> 密文
     */
    public byte[] encrypt(byte[] plainBytes, byte[] key) {
        // 生成密钥对象
        SecretKey secKey = generateSecretKey(key);

        // 获取 AES 密码器
        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, secKey);
            return cipher.doFinal(plainBytes);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException |
                 InvalidKeyException e) {
            throw new SecurityException("AES加密出错", e);
        }
        // 初始化密码器（加密模型）

        // 加密数据, 返回密文
    }

    /**
     * 数据解密: 密文 -> 明文
     */
    public byte[] decrypt(byte[] cipherBytes, byte[] key) {
        // 生成密钥对象
        SecretKey secKey = generateSecretKey(key);
        // 获取 AES 密码器
        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance("AES");
            // 初始化密码器（解密模型）
            cipher.init(Cipher.DECRYPT_MODE, secKey);
            // 解密数据, 返回明文
            return cipher.doFinal(cipherBytes);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException |
                 InvalidKeyException e) {
            throw new SecurityException("AES解密出错", e);
        }
    }
}
